package com.peaksport.framework.util;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import com.peaksport.framework.exception.PKBizException;
import com.peaksport.framework.exception.PKDevException;

public class PKCryptoUtils {
	
	private static final String CRYPTO_DEFAULT_KEY = "I'M JINBIN_GUO";
    
	/**
     * 加密
     * @param str
     * @return
     */
    public static String encrypt(String str) {
        return encrypt(str,CRYPTO_DEFAULT_KEY);
    }
    
    /**
     * 加密
     * @param str
     * @param cryptoKey 密匙,8位长度字符串
     * @return
     */
    public static String encrypt(String str,String cryptoKey) {
    	try {
	        Crypto crypto = new Crypto(cryptoKey);
	        return crypto.encrypt(str);
    	} catch (Exception exc) {
    		throw new PKBizException(exc.getMessage());
    	}
    }

    /**
     * 解密
     * @param str
     * @return
     */
    public static String decrypt(String str) throws Exception {
        return decrypt(str,CRYPTO_DEFAULT_KEY);
    }
    
    /**
     * 解密
     * @param str
     * @param cryptoKey 密匙,8位长度字符串
     * @return
     * @throws Exception
     */
    public static String decrypt(String str,String cryptoKey) throws Exception {
        Crypto crypto = new Crypto(cryptoKey);
        return crypto.decrypt(str);
    }

    /**
     * 加密类
     * @author jinbin_guo
     *
     */
    private static class Crypto {
        private String DES = "DES";
        private Cipher encryptCipher = null;
        private Cipher decryptCipher = null;
        
        /**
         * 指定密钥构造方法
         *
         * @param strKey 指定的密钥
         * @throws Exception
         */
        public Crypto(String strKey) throws Exception {
            if (strKey == null || strKey.length() != 8) {
                throw new PKDevException("密匙必须为8位的字符串.");
            }
            // DES算法要求有一个可信任的随机数源
            SecureRandom sr = new SecureRandom();
            // 从原始密匙数据创建一个DESKeySpec对象
            DESKeySpec dks = new DESKeySpec(strKey.getBytes());
            // 创建一个密匙工厂，然后用它把DESKeySpec对象转换成
            // 一个SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
            SecretKey securekey = keyFactory.generateSecret(dks);

            encryptCipher = Cipher.getInstance(DES);
            encryptCipher.init(Cipher.ENCRYPT_MODE,securekey, sr);

            decryptCipher = Cipher.getInstance(DES);
            decryptCipher.init(Cipher.DECRYPT_MODE,securekey, sr);
        }

        /**
         * 密码解密
         * @param data
         * @return
         * @throws Exception
         */
        public final String decrypt(String data) {
            try {
                byte[] s =  decryptCipher.doFinal(hex2byte(data.getBytes()));
                return new String(s);
            } catch (Exception e) {
                throw new PKDevException("解密异常:" + e.getMessage());
            }
        }

        /**
         * 密码加密
         * @param str
         * @return
         * @throws Exception
         */
        public final String encrypt(String str) {
            try {
                return byte2hex(encryptCipher.doFinal(str.getBytes()));
            } catch (Exception e) {
                throw new PKDevException("加密异常:" + e.getMessage());
            }
        }

        /**
         * 二行制转字符串
         * @param b
         * @return
         */
        private String byte2hex(byte[] b) {

            String hs = "";
            String stmp = "";
            for (int n = 0; n < b.length; n++) {
                stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
                if (stmp.length() == 1)
                    hs = hs + "0" + stmp;
                else
                    hs = hs + stmp;
            }
            return hs.toUpperCase();
        }

        private byte[] hex2byte(byte[] b) {

            if ((b.length % 2) != 0)
                throw new IllegalArgumentException("长度不是偶数");
            byte[] b2 = new byte[b.length / 2];
            for (int n = 0; n < b.length; n += 2) {
                String item = new String(b, n, 2);
                b2[n / 2] = (byte) Integer.parseInt(item, 16);
            }
            return b2;
        }
    }
}
